/**
 * 类的继承
 * 1. Class 可以通过extends关键字实现继承，让子类继承父类的属性和方法。
 * 2. 当子类有构造函数时，必须首先调用 super()，以初始化父类的属性。如果你在调用 super() 之前就尝试访问 this，会导致错误。
 * 3. 子类可以访问父类的静态属性和方法。
 * 4. 有同名属性和方法的情况下，this关键字调用的是子类的属性和方法
 * 5. 子类不存在，只有父类的有的属性和方法，this关键字调用父类的方法
 * 6. 父类的属性 使用super关键字调用不到
 */

// 1. 继承父类案例
class Fn {
  static sBar = '父类静态属性sBar'
  #name = '父类私有属性#name'
  sex = '父类普通属性sex'

  get name(){
    return this.#name
  }

  set name(value){
    this.#name = value
  }

  static bar(){
    this.baz()
  }
  static baz(){
    console.log('父类静态方法baz');  
  }
  baz(){
    console.log('父类：world######'+this.#name);
  }
  bazfn(){
    this.baz()
  }
}

class Shuiguo2 extends Fn {}

let sg2 = new Shuiguo2()
console.log(sg2.name); // 父类私有属性#name  从get方法中获取
sg2.name = '修改：父类私有属性#name'
console.log(sg2.name); // 修改：父类私有属性#name 可修改私有属性
sg2.sex = '修改：父类普通属性sex'
console.log(sg2.sex); // 修改：父类普通属性sex 可修改普通属性
sg2.bazfn() // 父类：world######父类私有属性#name  可调用父类普通方法
Shuiguo2.bar() // 父类静态方法baz  可调用父类静态方法
console.log(Shuiguo2.sBar) // 父类静态属性sBar  可调用父类静态属性;

// 2. 继承注意事项 和 super关键字

class Fn2 {

  static sBar = '父类静态属性sBar'
  #name = '父类私有属性#name'
  sex = '父类普通属性sex'
  age = 22

  constructor(msg){
    console.log(msg);
  }

  get name (){
    return this.#name
  }

  set name (value){
      this.#name = value
  }

  static bar() {
    this.baz();
  }

  static baz() {
    console.log('父类：静态方法baz');
  }

  baz() {
    console.log('父类：world#######'+this.#name);
  }

  bazfn3() {
    this.baz()
  }
  func1(){
    console.log('只有父类有这个方法func1');
  }
}

class Shuiguo3 extends Fn2 {
  name
  // sex = '子类的sex'
  constructor(name){
    super('调用了父类的构造方法')
    this.name = name
  }
  bazfn333(){
    console.log('--------------------');

    super.bazfn3()     // 父类：world#######父类私有属性#name
    console.log(super.name); // 父类私有属性#name
    super.name = 'ccc'  
    console.log(super.name);  // ccc
    
    this.bazfn3()   // 子类：world########pingguo
    console.log(this.name);  // pingguo

    console.log(this.age);  //22
    this.func1() // 只有父类有这个方法func1

    console.log(super.sex); //undefined  父类的属性 使用super关键字调用不到
    console.log('--------------------');
  }
  bazfn3(){
    console.log('子类：world########'+this.name);
  }
}

// let sg3 = new Shuiguo3('pingguo')
// let sg3 = new Shuiguo3()
// console.log(sg3.name); // pingguo  子类构造函数中调用父类构造函数，并传入参数

let sg4 = new Shuiguo3('pingguo')
sg4.bazfn333() // 父类：world#######pingguo  子类调用父类方法，并传入参数